/**
* Copyright (C) 2018-2020
* All rights reserved, Designed By www.gzchengguo.cn
* 注意：
* 本软件为www.gzchengguo.cn开发研制，未经购买不得商用
* 购买后可获得全部源代码（禁止转卖、分享、上传到码云、github等开源平台）
* 一经发现盗用、分享等行为，将追究法律责任，后果自负
*/
package link.chengguo.orangemall.modules.category.service.impl;

import link.chengguo.orangemall.common.service.impl.BaseServiceImpl;
import link.chengguo.orangemall.common.utils.QueryHelpPlus;
import link.chengguo.orangemall.dozer.service.IGenerator;
import link.chengguo.orangemall.enums.ShopCommonEnum;
import link.chengguo.orangemall.modules.category.domain.OrangeStoreCategory;
import link.chengguo.orangemall.modules.category.service.OrangeStoreCategoryService;
import link.chengguo.orangemall.modules.category.service.dto.OrangeStoreCategoryDto;
import link.chengguo.orangemall.modules.category.service.dto.OrangeStoreCategoryQueryCriteria;
import link.chengguo.orangemall.modules.category.service.mapper.StoreCategoryMapper;
import link.chengguo.orangemall.utils.CateDTO;
import link.chengguo.orangemall.utils.FileUtil;
import link.chengguo.orangemall.utils.TreeUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Maps;
import lombok.AllArgsConstructor;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;


/**
* @author chengguo
* @date 2020-05-12
*/
@Service
@AllArgsConstructor
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class OrangeStoreCategoryServiceImpl extends BaseServiceImpl<StoreCategoryMapper, OrangeStoreCategory> implements OrangeStoreCategoryService {

    private final IGenerator generator;

    /**
     * 获取分类列表树形列表
     * @return List
     */
    @Override
    public List<CateDTO> getList() {
        QueryWrapper<OrangeStoreCategory> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(OrangeStoreCategory::getIsShow, ShopCommonEnum.SHOW_1.getValue())
                .orderByAsc(OrangeStoreCategory::getSort);
        List<CateDTO> list = generator.convert(baseMapper.selectList(wrapper),CateDTO.class);
        return TreeUtil.list2TreeConverter(list,0);
    }

    //===============================//

    @Override
    public Map<String, Object> queryAll(OrangeStoreCategoryQueryCriteria criteria, Pageable pageable) {
        getPage(pageable);
        PageInfo<OrangeStoreCategoryDto> page = new PageInfo<>(queryAll(criteria));
        Map<String, Object> map = new LinkedHashMap<>(2);
        map.put("content", page.getList());
        map.put("totalElements", page.getTotal());
        return map;
    }


    @Override
    public List<OrangeStoreCategoryDto> queryAll(OrangeStoreCategoryQueryCriteria criteria){
        return generator.convert(this.baseMapper.selectList(QueryHelpPlus.getPredicate(OrangeStoreCategory.class, criteria)),
                OrangeStoreCategoryDto.class);
    }


    @Override
    public void download(List<OrangeStoreCategoryDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (OrangeStoreCategoryDto orangeStoreCategory : all) {
            Map<String,Object> map = new LinkedHashMap<>();
            map.put("父id", orangeStoreCategory.getPid());
            map.put("分类名称", orangeStoreCategory.getCateName());
            map.put("排序", orangeStoreCategory.getSort());
            map.put("图标", orangeStoreCategory.getPic());
            map.put("是否推荐", orangeStoreCategory.getIsShow());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }

    /**
     * 构建树形
     * @param categoryDTOS 分类列表
     * @return map
     */
    @Override
    public Map<String, Object> buildTree(List<OrangeStoreCategoryDto> categoryDTOS) {
        Set<OrangeStoreCategoryDto> trees = new LinkedHashSet<>();
        Set<OrangeStoreCategoryDto> cates = new LinkedHashSet<>();
        List<String> deptNames = categoryDTOS.stream().map(OrangeStoreCategoryDto::getCateName)
                .collect(Collectors.toList());

        //OrangeStoreCategoryDto categoryDTO = new OrangeStoreCategoryDto();
        Boolean isChild;
        List<OrangeStoreCategory> categories = this.list();
        for (OrangeStoreCategoryDto deptDTO : categoryDTOS) {
            isChild = false;
            if ("0".equals(deptDTO.getPid().toString())) {
                trees.add(deptDTO);
            }
            for (OrangeStoreCategoryDto it : categoryDTOS) {
                if (it.getPid().equals(deptDTO.getId())) {
                    isChild = true;
                    if (deptDTO.getChildren() == null) {
                        deptDTO.setChildren(new ArrayList<OrangeStoreCategoryDto>());
                    }
                    deptDTO.getChildren().add(it);
                }
            }
            if (isChild) {
                cates.add(deptDTO);
            }
            for (OrangeStoreCategory category : categories) {
                if (category.getId().equals(deptDTO.getPid()) && !deptNames.contains(category.getCateName())) {
                    cates.add(deptDTO);
                }
            }
        }


        if (CollectionUtils.isEmpty(trees)) {
            trees = cates;
        }


        Integer totalElements = categoryDTOS != null ? categoryDTOS.size() : 0;

        Map<String, Object> map = Maps.newHashMap();
        map.put("totalElements", totalElements);
        map.put("content", CollectionUtils.isEmpty(trees) ? categoryDTOS : trees);
        return map;
    }


    /**
     * 检测分类是否操过二级
     * @param pid 父级id
     * @return boolean
     */
    @Override
    public boolean checkCategory(int pid){
        if(pid == 0) {
            return true;
        }
        OrangeStoreCategory orangeStoreCategory =  this.getOne(Wrappers.<OrangeStoreCategory>lambdaQuery()
                        .eq(OrangeStoreCategory::getId,pid));
        if(orangeStoreCategory.getPid() > 0) {
            return false;
        }

        return true;
    }

    /**
     * 检测商品分类必选选择二级
     * @param id 分类id
     * @return boolean
     */
    @Override
    public boolean checkProductCategory(int id){
        OrangeStoreCategory orangeStoreCategory =  this.getOne(Wrappers.<OrangeStoreCategory>lambdaQuery()
                .eq(OrangeStoreCategory::getId,id));

        if(orangeStoreCategory.getPid() == 0) {
            return false;
        }

        return true;
    }

}
